package com.gitee.chessboard.scan.discern;

import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * 识别处理器
 *
 * @author 敲代码的旺财
 * @date 2021/12/10 15:55
 */
public class DiscernHandler {

    /**
     * 识别器
     * 用于对类进行处理和识别
     */
    List<DiscernPortion> portions;

    /**
     * 识别器 搜索缓存
     * Map<识别器的name，识别器>
     */
    Map<String, DiscernPortion> portionMap;

    /**
     * 标识识别器是否发生了更新；
     */
    boolean updateFlag;

    /**
     * 添加识别器
     *
     * @param discernPortion 识别器
     */
    public void addDiscern(DiscernPortion discernPortion) {
        if (portions == null) {
            portions = new CopyOnWriteArrayList<>();
        }
        portions.add(discernPortion);
        updateFlag = true;
    }

    /**
     * 添加识别器
     *
     * @param discernPortion 识别器
     * @param sort           排序顺序
     */
    public void addDiscern(DiscernPortion discernPortion, Integer sort) {
        if (portions == null) {
            portions = new CopyOnWriteArrayList<>();
        }
        portions.add(sort, discernPortion);
        updateFlag = true;
    }

    /**
     * 删除识别器
     *
     * @param discernPortion 识别器
     */
    public void removeDiscern(DiscernPortion discernPortion) {
        if (portions == null) {
            portions = new CopyOnWriteArrayList<>();
        }
        portions.remove(discernPortion);
        updateFlag = true;
    }

    /**
     * 删除识别器
     *
     * @param index 索引位置
     */
    public void removeDiscern(int index) {
        if (portions == null) {
            portions = new CopyOnWriteArrayList<>();
        }
        portions.remove(index);
        updateFlag = true;
    }

    /**
     * 获取识别器
     *
     * @param name 识别器的名称
     * @return 识别器
     */
    public DiscernPortion get(String name) {
        if (updateFlag) {
            portionMap = portions.stream().collect(Collectors.toMap(DiscernPortion::getName, m -> m));
        }
        return portionMap.get(name);
    }

    /**
     * 进行识别
     */
    public void discern(URL url) {
        if (portions == null || portions.size() == 0) {
            return;
        }
        DiscernPortion first = null;
        DiscernPortion last = null;
        for (DiscernPortion portion : portions) {
            if (last != null) {
                last.setNext(portion);
            } else {
                first = portion;
            }
            last = portion;
        }
        first.handle(url);
    }
}